package Prova;

import DisciplinaTopico.Topico;
import DisciplinaTopico.TopicoException;
import java.util.List;
import java.util.ArrayList;
import ProvaView.IProva;
import ProvaView.TelaProva;
import Questao.Dificuldade;
import javax.swing.JOptionPane;

public class Prova implements IProva
{
    private List<QuestaoProva> questoesProva = new ArrayList<QuestaoProva>();
    private List<Topico> topicos= new ArrayList<Topico>();
    private static Integer posicao = null;
    private static Integer numeroTopicos;
   
    public Prova()
    {
    }

    public Prova(List<QuestaoProva> questoesProva, List<Topico> topicos)
    {
        this.questoesProva = questoesProva;
        this.topicos = topicos;
    }


    public List<QuestaoProva> getQuestoesProva()
    {
        return questoesProva;
    }

    public void setQuestoesProva(List<QuestaoProva> questoesProva)
    {
        this.questoesProva = questoesProva;
    }

    public List<Topico> getTopicos()
    {
        return topicos;
    }

    public void setTopicos(List<Topico> topicos)
    {
        this.topicos = topicos;
    }

    private static int obterOrdemTopicos()
    {
        int posicaoTopico;

        if ((posicao == null)||(posicao >= numeroTopicos))
            posicao = 0;
        
        posicaoTopico = posicao;
        posicao++;

        return posicaoTopico;
    }

    private QuestaoProva obterQuestaoProva(List<Topico> topicosSelecionados, Dificuldade dif, String tipo) throws TopicoException
    {
        QuestaoProva questaoprova = new QuestaoProva();
        questaoprova.setQuestao(topicosSelecionados.get(obterOrdemTopicos()).getQuestao(dif,tipo));
        for (int iteracoes=0; iteracoes<topicosSelecionados.size(); iteracoes++)
        {
            if (questaoprova.getQuestao() != null)
                break;
            else
                questaoprova.setQuestao(topicosSelecionados.get(obterOrdemTopicos()).getQuestao(dif,tipo));
        }

        if (questaoprova.getQuestao()!=null)
        {
            questaoprova.setPontuacao(0.00);
            questaoprova.setPosicao(0);
            return questaoprova;
        }
        else
        {
            for (Topico top: topicosSelecionados)
                top.limpaQuestoesSelecionadas();

            throw new TopicoException("ERRO: Não existe questoes suficientes cadastradas no banco que atenda aos requisitos (Dificuldade: " + dif + ", Tipo: " + tipo + ")");
        }
    }

    public void gerarProva(int numQuestoesFaceisDisc,int numQuestoesMediasDisc, int numQuestoesDificiesDisc,
                            int numQuestoesFaceisMultEsc,int numQuestoesMediasMultEsc,int numQuestoesDificiesMultEsc,List<Topico> topicosSelecionados)throws Exception
    {
        numeroTopicos = topicosSelecionados.size();
        boolean adicionada = false;

        try
        {
            for(int cont = 0; cont < numQuestoesFaceisDisc; cont++)
            {
                questoesProva.add(obterQuestaoProva(topicosSelecionados,Dificuldade.Facil, "Discursiva"));
                adicionada = true;
            }

            for(int cont = 0; cont < numQuestoesMediasDisc; cont++)
            {
                questoesProva.add(obterQuestaoProva(topicosSelecionados, Dificuldade.Medio, "Discursiva"));
                adicionada = true;
            }

            for(int cont = 0; cont < numQuestoesDificiesDisc; cont++)
            {
                questoesProva.add(obterQuestaoProva(topicosSelecionados, Dificuldade.Dificil, "Discursiva"));
                adicionada = true;
            }

            for(int cont = 0; cont < numQuestoesFaceisMultEsc; cont++)
            {
                questoesProva.add(obterQuestaoProva(topicosSelecionados, Dificuldade.Facil, "Multipla Escolha"));
                adicionada = true;
            }

            for(int cont = 0; cont < numQuestoesMediasMultEsc; cont++)
            {
                questoesProva.add(obterQuestaoProva(topicosSelecionados, Dificuldade.Medio, "Multipla Escolha"));
                adicionada = true;
            }

            for(int cont = 0; cont < numQuestoesDificiesMultEsc; cont++)
            {
                questoesProva.add(obterQuestaoProva(topicosSelecionados, Dificuldade.Dificil, "Multipla Escolha"));
                adicionada = true;
            }

            if(!adicionada)
               throw new ProvaException("ERRO: Nenhuma questão foi adicionada a prova");

            TelaProva tela = new TelaProva(questoesProva);
            tela.setVisible(true);

        }
        catch(Exception e)
        {
            JOptionPane.showMessageDialog(null, "Exception recebida pela Prova" + e.getMessage(), "Erro!", JOptionPane.ERROR_MESSAGE, null);
        }
    }


    public boolean validaPontuacaoTotalProva (List<QuestaoProva> questoes) throws ProvaException
    {
        double pontuacaoTotal = 0.00;

        for (QuestaoProva questaoProva : questoes)
            pontuacaoTotal += questaoProva.getPontuacao();

        if(pontuacaoTotal == 10.00)
            return true;

        throw new ProvaException("ERRO: A soma da pontuação das questões tem que igual a 10.0 pontos!");
    }

    public boolean verificaPosicaoQuestoesProva (List<QuestaoProva> questoes) throws ProvaException
    {
        for (QuestaoProva questaoProva : questoes) 
            if(questaoProva.getPosicao() == 0)
                throw new ProvaException("ERRO: Todas as posições de questões precisam ser preenchidas!");
        
        return true;
    }


    public boolean verificaPontuacaoQuestao(double pontuacaoQuestao)throws ProvaException
    {
        if(pontuacaoQuestao <= 0.00 )
            throw new ProvaException ("ERRO: Pontuacao da questao deve ser maior que 0");
        return true;
    }

//    public int[] populaArrayPosicoesValidas(int[] posicoes, int posicaoAtual){
//           for (int posicao= 0; posicao < posicoes.length; posicao++) {
//                if(posicoes[posicao] == posicaoAtual)
//
//           }
//           return posicoes;
//
//    }

//    public boolean posicaoDisponivel(int[] posicoes, int posicao){
//        if(posicoes[posicao-1] == posicao){
//            return false;
//        }
//        posicoes[posicao-1]=posicao;
//        return true;
//    }
}
